package com.adms.service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.adms.domain.Message;
import com.adms.domain.MessageMapper;
import com.adms.domain.Reform;
import com.adms.domain.ReformExecute;
import com.adms.domain.ReformExecuteExample;
import com.adms.domain.ReformExecuteExample.Criteria;
import com.adms.domain.ReformExecuteMapper;
import com.adms.domain.ReformMapper;
import com.adms.domain.User;
import com.adms.util.AdmsConfig;
import com.adms.util.ShiroUtil;
import com.adms.websocket.WebSocketServer;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.github.pagehelper.util.StringUtil;

@Transactional
@Service
public class ReformExecuteService {

	@Autowired
	private ReformExecuteMapper reformExecuteMapper;
	@Autowired
	private ReformMapper reformMapper;
	@Autowired
	private MessageMapper messageMapper;
	@Autowired
	private WebSocketServer webSocketServer;

	public ReformExecute getByExecuteId(Integer executeId) {
		return reformExecuteMapper.selectByPrimaryKey(executeId);
	}

	public Map<String, Object> getByExecuteIdWithReform(Integer executeId) {
		return reformExecuteMapper.selectByPrimaryKeyWithReform(executeId);
	}

	public PageInfo<ReformExecute> list(ReformExecute reformExecute, String timeField, Date start, Date end,
			String orderByClause, Integer pageNum, Integer pageSize, Integer navigatePages) {

		ReformExecuteExample ex = constructExample(reformExecute, timeField, start, end, orderByClause);
		PageHelper.startPage(pageNum, pageSize);
		List<ReformExecute> reformExecutes = reformExecuteMapper.selectByExample(ex);
		return new PageInfo<>(reformExecutes, navigatePages);
	}

	private ReformExecuteExample constructExample(ReformExecute reformExecute, String timeField, Date start, Date end,
			String orderByClause) {
		ReformExecuteExample ex = new ReformExecuteExample();
		Criteria or = ex.or();
		if (reformExecute != null) {
			Integer reformId = reformExecute.getReformId();
			Integer gridAuditState = reformExecute.getGridAuditState();
			Integer envAuditState = reformExecute.getEnvAuditState();
			if (reformId != null) {
				or.andReformIdEqualTo(reformId);
			}
			if (gridAuditState != null) {
				or.andGridAuditStateEqualTo(gridAuditState);
			}
			if (envAuditState != null) {
				or.andEnvAuditStateEqualTo(envAuditState);
			}
		}

		if (StringUtil.isNotEmpty(timeField)) {
			if (timeField.equals("createTime")) {
				if (start != null) {
					if (end != null) {
						or.andCreateTimeBetween(start, end);
					} else {
						or.andCreateTimeGreaterThanOrEqualTo(start);
					}
				} else {
					if (end != null) {
						or.andCreateTimeLessThanOrEqualTo(end);
					}
				}
			}
			if (timeField.equals("gridAuditTime")) {
				if (start != null) {
					if (end != null) {
						or.andGridAuditTimeBetween(start, end);
					} else {
						or.andGridAuditTimeGreaterThanOrEqualTo(start);
					}
				} else {
					if (end != null) {
						or.andGridAuditTimeLessThanOrEqualTo(end);
					}
				}
			}
			if (timeField.equals("envAuditTime")) {
				if (start != null) {
					if (end != null) {
						or.andEnvAuditTimeBetween(start, end);
					} else {
						or.andEnvAuditTimeGreaterThanOrEqualTo(start);
					}
				} else {
					if (end != null) {
						or.andEnvAuditTimeLessThanOrEqualTo(end);
					}
				}
			}
		}

		if (StringUtil.isNotEmpty(orderByClause)) {
			ex.setOrderByClause(orderByClause);
		} else {
			ex.setOrderByClause("reform_execute.create_time desc");
		}
		return ex;
	}

	public boolean audit(Integer executeId, Integer reformId, Integer auditState, String auditView) {
		User loginUser = ShiroUtil.getUser();
		String loginRole = loginUser.getRole();
		Integer loginUserId = loginUser.getUserId();
		Reform reform = reformMapper.selectByPrimaryKey(reformId);
		ReformExecute reformExecute = reformExecuteMapper.selectByPrimaryKey(executeId);
		if (reformExecute.getGridAuditState() != 1 && loginUserId.equals(reform.getGridUserId())) {
			gridAudit(reform, reformExecute, executeId, reformId, auditState, auditView);
		} else if (reformExecute.getEnvAuditState() != 1 && (loginRole.equals(AdmsConfig.ROLE_ENVDEPARTMENT)
				|| loginRole.equals(AdmsConfig.ROLE_ENVLEADER) || loginRole.equals(AdmsConfig.ROLE_OFFICELEADER))) {
			envAudit(reform, reformExecute, executeId, reformId, auditState, auditView);
		}
		return true;
	}

	private void gridAudit(Reform reform, ReformExecute reformExecute, Integer executeId, Integer reformId,
			Integer auditState, String auditView) {
		// 更新审核单
		reformExecute.setGridAuditState(auditState);
		reformExecute.setGridAuditView(auditView);
		reformExecute.setGridAuditTime(new Date());
		reformExecuteMapper.updateByPrimaryKeySelective(reformExecute);
		// 新增站内信
		Integer envUserId = reform.getUserId();
		List<Integer> relativeUserIds = new ArrayList<>();
		relativeUserIds.add(reform.getHandleUserId());
		relativeUserIds.add(reform.getLegalUserId());
		Message message = new Message();
		message.setReformId(reformId);
		message.setExecuteId(executeId);
		message.setTitle(reform.getTitle());
		// 审核通过
		if (auditState == 1) {
			message.setType(AdmsConfig.MESSAGE_TYPE_HANDLEREFORM_PASS_BYGRID);
			// 加入环安科,因为要通知到环安科,交办人,负责人
			relativeUserIds.add(envUserId);
		}
		// 审核拒绝
		if (auditState == 2) {
			message.setType(AdmsConfig.MESSAGE_TYPE_HANDLEREFORM_FAIL_BYGRID);
			// 更新整改单可申请执行为true
			reform.setCanHandle(true);
			reformMapper.updateByPrimaryKey(reform);
		}
		for (Integer relativeUserId : relativeUserIds) {
			message.setUserId(relativeUserId);
			messageMapper.insertSelective(message);
			// 发送webSocket消息
			webSocketServer.sendMessage(relativeUserId, message);
			// 重置获取主键id为null
			message.setMessageId(null);
		}
	}

	private void envAudit(Reform reform, ReformExecute reformExecute, Integer executeId, Integer reformId,
			Integer auditState, String auditView) {
		// 更新审核单
		reformExecute.setEnvAuditState(auditState);
		reformExecute.setEnvAuditView(auditView);
		reformExecute.setEnvAuditTime(new Date());
		reformExecuteMapper.updateByPrimaryKeySelective(reformExecute);
		// 新增站内信
		List<Integer> relativeUserIds = new ArrayList<>();
		relativeUserIds.add(reform.getGridUserId());
		relativeUserIds.add(reform.getHandleUserId());
		relativeUserIds.add(reform.getLegalUserId());
		Message message = new Message();
		message.setReformId(reformId);
		message.setExecuteId(executeId);
		message.setTitle(reform.getTitle());
		// 审核通过
		if (auditState == 1) {
			message.setType(AdmsConfig.MESSAGE_TYPE_HANDLEREFORM_PASS_BYENV);
			if (!reform.getIsLeading()) {
				reform.setState(AdmsConfig.REFORM_STATE_ISFINISHED);
				reform.setFinishTime(new Date());
			}
			reform.setCanDefer(false);
			reform.setCanHandle(false);
			if (reform.getIsLeading()) {
				reform.setCanConfirm(true);
			}
		}
		// 审核拒绝
		if (auditState == 2) {
			reform.setCanDefer(true);
			reform.setCanHandle(true);
			if (reform.getIsLeading()) {
				reform.setCanConfirm(false);
			}
			message.setType(AdmsConfig.MESSAGE_TYPE_HANDLEREFORM_FAIL_BYENV);
		}
		for (Integer relativeUserId : relativeUserIds) {
			message.setUserId(relativeUserId);
			messageMapper.insertSelective(message);
			webSocketServer.sendMessage(relativeUserId, message);
			message.setMessageId(null);
		}
		reformMapper.updateByPrimaryKey(reform);
	}
}
